﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GraphInformation;
using QuickGraph;
using System.IO;
using GraphMLComplexType;

namespace EpidemicSimulator
{
    public static class QuickGraphExtension
    {
        public static UndirectedGraph<SocialNetworkNode, EdgeWithAttributes.EdgeWithAttributes<SocialNetworkNode>> GetGraphFormSilverlight(this GraphInformation.Graph inputGraph)
        {
            UndirectedGraph<SocialNetworkNode, EdgeWithAttributes.EdgeWithAttributes<SocialNetworkNode>> result = new UndirectedGraph<SocialNetworkNode, EdgeWithAttributes.EdgeWithAttributes<SocialNetworkNode>>();

            Dictionary<Guid, SocialNetworkNode> map = new Dictionary<Guid, SocialNetworkNode>();

            foreach (var item in inputGraph.Vertices)
            {
                SocialNetworkNode v = new SocialNetworkNode();
                map.Add(item.ID, v);
                //TODO: fix
                v.Id = item.ID.GetHashCode();
                v.Keys = new Dictionary<string, string>();
                foreach (var key in item.Keys)
                {
                    v.Keys.Add(key.Key, key.Value);
                }
                result.AddVertex(v);
            }

            foreach (var item in inputGraph.Edges)
            {
                result.AddEdge(new EdgeWithAttributes.EdgeWithAttributes<SocialNetworkNode>(map[item.Source], map[item.Target]));
            }

            return result;
        }



        public static GraphInformation.Graph GetInformationGraph(this UndirectedGraph<SocialNetworkNode, EdgeWithAttributes.EdgeWithAttributes<SocialNetworkNode>> inputGraph)
        {
            GraphInformation.Graph graph = new GraphInformation.Graph();

            graph.ID = Guid.NewGuid();

            var map = new Dictionary<SocialNetworkNode, GraphElement>();
            graph.Vertices = new List<GraphElement>();
            //var list = new List<GraphElement>();
            for (int i = 0; i < inputGraph.VertexCount; i++)
            {
                var v = inputGraph.Vertices.ElementAt(i);
                var elem = new GraphElement();
                elem.ID = Guid.NewGuid();
                elem.GraphID = graph.ID;
                elem.Keys = new List<PairKeyValue>();
                foreach (var element in v.Keys)
                {
                    elem.Keys.Add(new PairKeyValue() { ElementID = elem.ID, ID = Guid.NewGuid(), Key = element.Key, Value = element.Value});
                }
                graph.Vertices.Add(elem);
                map.Add(v, elem);
            }

            graph.Edges = new List<GraphEdge>();
            for (int i = 0; i < inputGraph.Edges.Count(); i++)
            {
                var e = inputGraph.Edges.ElementAt(i);
                graph.Edges.Add(new GraphEdge() { GraphID = graph.ID, ID = Guid.NewGuid(), Source = map[e.Source].ID, Target = map[e.Target].ID, Condition = e.Condition});
            }

            return graph;
        }

        public static void Merge(this GraphInformation.Graph graph, AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes.EdgeWithAttributes<IGraphMLComplexType>> toMerge)
        {
            foreach (var item in graph.Vertices)
            {
                //TODO: fix
                var f = from n in toMerge.Vertices where n.Id == item.ID.GetHashCode() select n;
                if (f.Count() == 1)
                {
                    item.Keys.Clear();
                    foreach (var key in f.First().Keys)
                    {
                        var k = new GraphInformation.PairKeyValue();
                        k.Key = key.Key;
                        k.Value = key.Value;
                        item.Keys.Add(k);
                    }
                }
            }
        }
    }

}
